// 带停止功能的中文语音合成模块
const say = require('say');
const { spawn } = require('child_process');

// 保存当前正在播放的语音进程
let currentSpeechProcess = null;

// 设置环境变量为 UTF-8
process.env.NODE_ICU_DATA = '';
process.env.LANG = 'zh_CN.UTF-8';
process.env.LC_ALL = 'zh_CN.UTF-8';
say.voice = 'Microsoft Kangkang Desktop - Chinese (Simplified)';

// 自定义 speak 函数，支持停止功能
say.speak = function(text, voice, speed = 0) {
    // 先停止任何正在播放的语音
    if (currentSpeechProcess) {
        stopSpeech();
    }
    
    // 转义单引号以避免 PowerShell 语法错误
    const escapedText = text.replace(/'/g, "`'");
    
    // 启动新的语音播放进程
    currentSpeechProcess = spawn('PowerShell', [
        '-Command',
        `[Console]::OutputEncoding = [Text.Encoding]::UTF8;`,
        `Add-Type –AssemblyName System.Speech;`,
        `$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;`,
        `$speak.Rate = ${speed};`,
        `$speak.Speak('${escapedText}')`
    ]);

    currentSpeechProcess.stderr.on('data', (data) => {
        console.error(`PowerShell 错误: ${data}`);
    });

    currentSpeechProcess.on('close', (code) => {
        // 进程结束时清除引用
        currentSpeechProcess = null;
        console.log(`语音播放进程已关闭，退出码: ${code}`);
    });
};

// 停止正在播放的语音函数
say.stop = function() {
    if (currentSpeechProcess) {
        console.log('正在停止语音播放...');
        // 强制终止 PowerShell 进程
        currentSpeechProcess.kill('SIGTERM');
        // 在 Windows 上可能需要使用不同的终止信号
        if (process.platform === 'win32') {
            currentSpeechProcess.kill();
        }
        currentSpeechProcess = null;
        console.log('语音播放已停止');
    } else {
        console.log('当前没有正在播放的语音');
    }
};

// 导出增强版的 say 对象
module.exports = {
    say
};

// // 示例用法（如果直接运行此脚本）
// if (require.main === module) {
//     // 播放一段较长的文本以便测试停止功能
//     const longText = '这是一段测试文本，用于演示如何在语音播放到一半时停止。你可以在任意时刻调用 stop() 函数来中断语音播放。这段文本需要足够长，以便你有时间测试停止功能。';
    
//     console.log('开始播放语音...');
//     say.speak(longText);
    
//     // 5秒后自动停止播放（用于演示）
//     setTimeout(() => {
//         console.log('5秒后自动停止播放');
//         say.stop();
//     }, 5000);
// }